package run.halo.app.core.reconciler;

import static run.halo.app.extension.ExtensionUtil.addFinalizers;
import static run.halo.app.extension.ExtensionUtil.removeFinalizers;

import java.util.Map;
import java.util.Set;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import run.halo.app.core.extension.content.Product;
import run.halo.app.extension.ExtensionClient;
import run.halo.app.extension.ExtensionUtil;
import run.halo.app.extension.MetadataUtil;
import run.halo.app.extension.controller.Controller;
import run.halo.app.extension.controller.ControllerBuilder;
import run.halo.app.extension.controller.Reconciler;

/**
 * Reconciler for {@link Product}.
 * 负责处理产品的标签设置和状态更新
 *
 * @author halo-product-management
 * @since 2.0.0
 */
@Component
@RequiredArgsConstructor
public class ProductReconciler implements Reconciler<Reconciler.Request> {
    static final String FINALIZER_NAME = "product-protection";
    private final ExtensionClient client;

    @Override
    public Result reconcile(Request request) {
        client.fetch(Product.class, request.name())
            .ifPresent(product -> {
                if (ExtensionUtil.isDeleted(product)) {
                    if (removeFinalizers(product.getMetadata(), Set.of(FINALIZER_NAME))) {
                        client.update(product);
                    }
                    return;
                }

                addFinalizers(product.getMetadata(), Set.of(FINALIZER_NAME));

                // 设置产品类型引用标签
                populateProductTypeRefLabel(product);

                // 更新观察版本
                var status = product.getStatusOrDefault();
                status.setObservedVersion(product.getMetadata().getVersion());

                client.update(product);
            });
        return Result.doNotRetry();
    }

    private void populateProductTypeRefLabel(Product product) {
        Map<String, String> labels = MetadataUtil.nullSafeLabels(product);
        String productTypeRef = product.getSpec().getProductTypeRef();
        
        if (StringUtils.hasText(productTypeRef)) {
            String oldProductTypeRef = labels.get(Product.PRODUCT_TYPE_REF_LABEL);
            
            // 只有当标签值发生变化时才更新
            if (!productTypeRef.equals(oldProductTypeRef)) {
                labels.put(Product.PRODUCT_TYPE_REF_LABEL, productTypeRef);
            }
        } else {
            // 如果productTypeRef为空，移除标签
            labels.remove(Product.PRODUCT_TYPE_REF_LABEL);
        }
    }

    @Override
    public Controller setupWith(ControllerBuilder builder) {
        return builder
            .extension(new Product())
            .syncAllOnStart(true) // 启动时同步所有现有产品
            .build();
    }
}